home *** CD-ROM | disk | FTP | other *** search
/ Programmers Heaven 2 / Programmers Heaven 2.iso / files / graphics / library / wgt51_r2.zip / WGT5 / EXAMPLES / WGT56.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-03  |  10.6 KB  |  357 lines

  1. /*
  2. ==============================================================================
  3.               WordUp Graphics Toolkit Version 5.0
  4.                  Demonstration Program 56
  5.  
  6.  This program uses the scrolling library to create a parallax scrolling      
  7.  world with two layers.  There are three kinds of objects in the world;      
  8.  clouds, yellow balls (wearing shades) that move behind the front layer,     
  9.  and yellow balls that move in front.  Use the arrow keys to move around     
  10.  and ESC will exit.                                                          
  11.  
  12.  *** PROJECT ***                                                             
  13.  This program requires the files WGT5_WC.LIB and WSCR_WC.LIB to be linked.   
  14.                                           
  15.  *** DATA FILES ***                                                          
  16.  PARABACK.SPR, PARAFRON.SPR, PARASPR.SPR, PARAMAPB.WMP, PARAMAPF.WMP         
  17.                                WATCOM C++ VERSION 
  18. ==============================================================================
  19. */
  20.  
  21. #include <stdlib.h>
  22. #include <dos.h>
  23. #include <wgt5.h>
  24. #include <wgtscrol.h>
  25.  
  26.  
  27. #define WIND_SIZEX 20 /* Set scrolling window dimensions (in tiles) */
  28. #define WIND_SIZEY 13
  29.  
  30. #define SPEED 8       /* Speed of scrolling */
  31.  
  32. #define LEFT 75       /* Keyboard codes */
  33. #define RIGHT 77
  34. #define UP 72
  35. #define DOWN 80
  36. #define ESC 1
  37. #define KEY_S 31
  38. #define KEY_L 38
  39.  
  40.  
  41. #define BACKWIN 0       /* The NORMAL layer */
  42. #define FRONTWIN 1      /* The PARALLAX layer */
  43.  
  44. block backtiles[256];           /* Tiles, objects and tiles types for the */
  45. scrollsprite backobject[200];   /* background window. */
  46. short backtypes[256];
  47.  
  48. block fronttiles[256];          /* Tiles, objects and tiles types for the */
  49. scrollsprite frontobject[200];  /* foreground window. */
  50. short fronttypes[256];
  51.  
  52. block sprites[50];              /* The sprite images */
  53.  
  54. int timer;                      /* Counts timer ticks */
  55.  
  56. color pal[256];
  57.  
  58. short movex, movey;               /* Amount to scroll the front */
  59. short bmovex, bmovey;             /* Amount to scroll the back */
  60.  
  61. short x, y;                       /* Current viewing coordinates */
  62.                                   /* The window tries to center itself on
  63.                                      this coordinate. */
  64.  
  65. short num_clouds;         /* Number of cloud sprites on background */
  66. short num_ball_behind;    /* Number of yellow balls behind front layer.
  67.                All yellow balls with object numbers 100-199 are
  68.                drawn between the background and foreground 
  69.                layers. */
  70. short num_ball_infront;   /* Number of yellow balls in front of every layer */
  71.  
  72. short cloud_speed[100];   /* Movement speed and direction for clouds */
  73.  
  74. short oldmode;            /* Old video mode */
  75.  
  76. wgtmap backmap;  /* Holds the scrolling map */
  77. wgtmap frontmap;  /* Holds the scrolling map */
  78.  
  79.  
  80. void find_sprites (void)
  81. /* Searches for the maximum object numbers for each of the three categories
  82.    of wobjects. (clouds, ball behind, ball in front) */
  83. {
  84.  short i;
  85.  
  86.  num_clouds = 0;
  87.  for (i = 0; i < 100; i++)
  88.    if (backobject[i].on)
  89.       num_clouds = i;
  90.  
  91.  num_ball_behind = 0;
  92.  for (i = 100; i < 200; i++)
  93.    if (frontobject[i].on)
  94.       num_ball_behind = i;
  95.  
  96.  num_ball_infront = 0;
  97.  for (i = 0; i < 100; i++)
  98.    if (frontobject[i].on)
  99.       num_ball_infront = i;
  100. }
  101.  
  102.  
  103. void set_cloud_movements (void)
  104. /* Sets up the movement and speed for clouds */
  105. {
  106.   short i;
  107.  
  108.   for (i = 0; i < num_clouds; i++)
  109.   {
  110.     cloud_speed[i] = (rand () % 6)-3;
  111.     if (cloud_speed[i] == 0)
  112.       cloud_speed[i] = 1;
  113.   }
  114. }
  115.  
  116.  
  117. void move_clouds (scrollsprite *s)
  118. /* Moves the clouds and wraps them around the map if needed */
  119. {
  120.   short i;
  121.   short maxx;
  122.  
  123.   maxx = mapwidth[BACKWIN] * tilewidth[BACKWIN];
  124.  
  125.   for (i = 0; i < num_clouds; i++)
  126.   {
  127.     backobject[i].x += cloud_speed[i];
  128.     if (backobject[i].x < -80)
  129.        backobject[i].x = maxx;
  130.     else if (backobject[i].x > maxx)
  131.        backobject[i].x = -80;
  132.    }
  133. }
  134.  
  135.  
  136. void move_balls (void)
  137. /* Moves the balls around randomly */
  138. {
  139.   short i;
  140.   short maxx, maxy;
  141.  
  142.   maxx = mapwidth[BACKWIN] * tilewidth[BACKWIN];
  143.   maxy = mapheight[BACKWIN] * tileheight[BACKWIN];
  144.  
  145.   for (i = 0; i <= num_ball_infront; i++)
  146.   {
  147.     frontobject[i].x += (rand () % 17) - 8;    /* Randomly move the ball */
  148.     frontobject[i].y += (rand () % 17) - 8;
  149.  
  150.     if (frontobject[i].x < 0)                   /* Check the X boundaries */
  151.       frontobject[i].x = 0;
  152.     else if (frontobject[i].x > maxx)
  153.       frontobject[i].x = maxx;
  154.  
  155.     if (frontobject[i].y < 0)                   /* Check the Y boundaries */
  156.       frontobject[i].y = 0;
  157.     else if (frontobject[i].y > maxy)
  158.       frontobject[i].y = maxy;
  159.   }
  160.  
  161.   for (i = 100; i <= num_ball_behind; i++)
  162.    /* Do the same with the balls behind the front layer. */
  163.   {
  164.     frontobject[i].x += (rand () % 17) - 8;
  165.     frontobject[i].y += (rand () % 17) - 8;
  166.  
  167.     if (frontobject[i].x < 0)
  168.       frontobject[i].x = 0;
  169.     else if (frontobject[i].x > maxx)
  170.       frontobject[i].x = maxx;
  171.     if (frontobject[i].y < 0)
  172.       frontobject[i].y = 0;
  173.     else if (frontobject[i].y > maxy)
  174.       frontobject[i].y = maxy;
  175.   }
  176. }
  177.  
  178.  
  179. void timerctr (void)
  180. {
  181.   timer++;
  182. }
  183.  
  184.  
  185. void main (void)
  186. {
  187.   float seconds, fps;
  188.   int frames = 0;  
  189.  
  190.   oldmode = wgetmode ();
  191.   if (!vgadetected ())
  192.   {
  193.     printf ("VGA is required to run this program...");
  194.     exit (1);
  195.   }
  196.   printf ("WGT Example #56\n\n");
  197.  
  198.   printf ("This program uses the scrolling library to create a parallax scrolling\n");
  199.   printf ("world with two layers.  There are three kinds of objects in the world\n");
  200.   printf ("clouds, yellow balls (wearing shades) that move behind the front layer,\n");
  201.   printf ("and yellow balls that move in front.  Use the arrow keys to move around\n");
  202.   printf ("and ESC will exit.\n");
  203.   printf ("You can also save and load the map by pressing S and L.\n");
  204.   printf ("\nPress any key to begin\n");
  205.   getch ();
  206.  
  207.  
  208.   vga256 ();
  209.  
  210.   wloadsprites (pal, "paraspr.spr", sprites, 0, 49);
  211.  
  212.   wloadsprites (pal, "paraback.spr", backtiles, 0, 255);
  213.   wloadsprites (pal, "parafron.spr", fronttiles, 0, 255);
  214.   wsetpalette (0, 255, pal);
  215.  
  216.   winitscroll (BACKWIN, NORMAL, 0, WIND_SIZEX / 2, WIND_SIZEY / 2, backtiles);
  217.   /* Uses half the size since the background tiles are twice as big (32x32) */
  218.  
  219.   winitscroll (FRONTWIN, PARALLAX, BACKWIN, WIND_SIZEX, WIND_SIZEY, fronttiles);
  220.   /* Link this window to the background one */
  221.  
  222.   backmap  = wloadmap (BACKWIN, "paramapb.wmp", backtypes, backobject);
  223.   frontmap = wloadmap (FRONTWIN, "paramapf.wmp", fronttypes, frontobject);
  224.   /* Load the maps in for both windows */
  225.  
  226.   wshowwindow (BACKWIN, 0, 0);
  227.   wshowwindow (FRONTWIN, 0, 0);
  228.   /* Set the initial viewing coordinates. */
  229.  
  230.   find_sprites ();
  231.   set_cloud_movements ();
  232.  
  233.   installkbd ();                 /* Install the custom keyboard handler */
  234.   timer = 0;
  235.   winittimer ();
  236.   wstarttimer (timerctr, TICKS(70));
  237.   do {
  238.     move_clouds (backobject);
  239.     move_balls ();
  240.  
  241.     if (kbdon[LEFT])             /* Change the viewing coordinates */
  242.     {
  243.       x -= 8;
  244.       if (x < 0)
  245.     x = 0;
  246.     }
  247.     if (kbdon[RIGHT])
  248.     {
  249.       x += 8;
  250.       if (x > worldmaxx[FRONTWIN]) 
  251.     x = worldmaxx[FRONTWIN];
  252.     }
  253.     if (kbdon[UP])
  254.     {
  255.       y -= 8;
  256.       if (y < 0) 
  257.     y = 0;
  258.     }
  259.     if (kbdon[DOWN])
  260.     {
  261.       y += 8;
  262.       if (y > worldmaxy[FRONTWIN]) 
  263.     y = worldmaxy[FRONTWIN];
  264.     }
  265.  
  266.     /* Move the foreground by finding the difference between the actual
  267.        world coordinates and the desired world coordinates.  This will
  268.        make sure the window is centered on the (x,y) coordinate. */
  269.     movex = x - worldx[FRONTWIN]; 
  270.     movey = y - worldy[FRONTWIN];
  271.  
  272.     bmovex = worldx[FRONTWIN] + movex;
  273.     bmovey = worldy[FRONTWIN] + movey;
  274.     /* World coordinates of the front windows, after the current move */
  275.  
  276.     /* We must 'clip' them */
  277.     if (bmovex < 0)
  278.         bmovex = 0;
  279.     if (bmovey < 0)
  280.         bmovey = 0;
  281.     if (bmovex > worldmaxx[FRONTWIN] - 1)
  282.         bmovex = worldmaxx[FRONTWIN] - 1;
  283.     if (bmovey > worldmaxy[FRONTWIN] - 1)
  284.         bmovey = worldmaxy[FRONTWIN] - 1;
  285.  
  286.     /* Now make the background coordinates a percentage of the front window */
  287.     bmovex = bmovex * 4 / 5;
  288.     bmovey = bmovey * 9 / 10;
  289.  
  290.     worldx[BACKWIN] = bmovex;    
  291.     worldy[BACKWIN] = bmovey;    
  292.     /* Set the new background window coordinates */
  293.  
  294.     wscrollwindow (BACKWIN, 0, 0);
  295.     /* Display the background layer. (Layers are drawn from back to front.) */
  296.     /* No need to scroll by a value, because we already moved it by
  297.        changing worldx and worldy */
  298.  
  299.  
  300.     wshowobjects(BACKWIN, 0, num_clouds, sprites, backobject);
  301.     /* Show the clouds next */
  302.  
  303.     wshowobjects(BACKWIN, 100, num_ball_behind, sprites, frontobject);
  304.     /* Show the balls that are behind the front layer. (They will be just in 
  305.        front of the clouds) */
  306.    
  307.     wscrollwindow (FRONTWIN, movex, movey);
  308.     /* Display the foreground layer */
  309.  
  310.     wshowobjects(FRONTWIN, 0, num_ball_infront, sprites, frontobject);
  311.     /* Show the balls that are in front of everything else. */
  312.  
  313.     wnormscreen ();
  314.     /* Uncomment the following line to time with the vertical retrace */
  315.     // wretrace();
  316.     wputblock (0, 0, scrollblock[BACKWIN], 0);
  317.     /* Once the image is built, display the whole thing on the visual screen. */
  318.  
  319.     if (kbdon[KEY_S])      /* Save the map */
  320.     {
  321.       while (kbdon[KEY_S] == 1)
  322.         wretrace ();      /* Wait until the user releases the S key */
  323.       wsavemap (FRONTWIN, "savefron.wmp", frontmap, fronttypes, frontobject, num_ball_behind+1);
  324.       wsavemap (BACKWIN, "saveback.wmp", backmap, backtypes, backobject, num_clouds+1);
  325.     }
  326.     if (kbdon[KEY_L])      /* Load the map */
  327.     {
  328.       while (kbdon[KEY_L])
  329.         wretrace ();        /* Wait until the user releases the L key */
  330.       wfreemap (frontmap);  /* Free the maps that are already in memory */
  331.       wfreemap (backmap);
  332.       frontmap = wloadmap (FRONTWIN, "savefron.wmp", fronttypes, frontobject);
  333.       backmap = wloadmap (BACKWIN, "saveback.wmp", backtypes, backobject);
  334.     }
  335.     frames++;
  336.   } while (kbdon[ESC] == 0);
  337.   wstoptimer ();
  338.   wdonetimer ();
  339.  
  340.   /* Now clean up everything */
  341.   wendscroll (FRONTWIN);
  342.   wendscroll (BACKWIN);
  343.  
  344.   uninstallkbd ();
  345.   wfreesprites (fronttiles, 0, 255);
  346.   wfreesprites (backtiles, 0, 255);
  347.   wfreesprites (sprites, 0, 49);
  348.   wfreemap (backmap);
  349.   wfreemap (frontmap);
  350.   wsetmode (oldmode);
  351.   seconds = (float)(timer / 70.0);
  352.   fps = (float)(frames) / seconds;
  353.   printf ("Frames completed: %d\n", frames);
  354.   printf ("Seconds elapsed:  %g\n", seconds);
  355.   printf ("FPS: %g\n", fps);
  356. }
  357.